$(document).ready(function() {
    var namespace = '/ns';
    var ws_url = [location.protocol, '//', document.domain, ':', location.port, namespace].join('');
    console.log(ws_url);
    var socket = io.connect(ws_url, {
        path: '/ws/'
    });
    socket.on('connect', function() {
        socket.emit('client-connect', {data: 'I\'m connected!'});
    });
    socket.on('server_response', function(data) {
        console.log(data);
    });
    socket.on('server_broadcast', function(data) {
        console.log(data);
    });
    // socketio.send() method -> on_message
    socket.on('message', function(data) {
        console.log(data);
        socket.send('i got data')
    });
    socket.on('my_response', function(data) {
        console.log(data);
    });
    socket.on('emit_test', function(message) {
        console.log((new Date()).getTime() / 1000.0);
        console.log(message);
        console.log('--------------------------------------------');
    });
    socket.on('send_log', function(message) {
        if(message.msg && message.msg.columns && message.msg.data) {
            console.table(message.msg.data);
        }
        else {
            console.log(message);
        }
    });
    socket.on('ajax_queue', function(message) {
        console.log(message)
        try {
            var data = JSON.parse(message);
            // var url = get_ajax_url(data.action);
            switch(data.action) {
                case '1':
                    // TODO
                    break;
                case '2':
                    // TODO
                    break;
                default:
                    break;
            }
        }
        catch (ex) {
            console.log(ex);
        }
    });
    /*
     // refer: 
     // socket.emit allows you to emit custom events on the server and client
     // socket.send sends messages which are received with the `message` event
     //
     // socket.send(message)     ==>     socket.emit('message', message);
    */
    

    var $panel = $('body');
    var $editor_elem = $panel.find('.sql-editor');

    // https://docs.reduxframework.com/extensions/codemirror/
    var mime = 'text/x-plsql';
    var editor = CodeMirror.fromTextArea($editor_elem[0], {
        mode: mime,
        // hint: CodeMirror.hint.sql,
        indentWithTabs: true,
        smartIndent: true,
        lineNumbers: true,
        lineWrapping: false,
        styleActiveLine: true,
        matchBrackets : true,
        autofocus: true,
        foldGutter: true,
        gutters: ["breakpoints", "CodeMirror-linenumbers", "CodeMirror-foldgutter"],
        keyMap: "sublime",
        autoCloseBrackets: true,
        matchBrackets: true,
        showCursorWhenSelecting: true,
        tabSize: 4,
        // theme: 'monokai',
        extraKeys: {
            "Ctrl-Enter": "autocomplete",
            "Ctrl-F11": function(cm) {
                cm.setOption("fullScreen", !cm.getOption("fullScreen"));
            }
        },
        hintOptions: {tables: {
            users: {name: null, score: null, birthDate: null},
            countries: {name: null, population: null, size: null}
        }}
    });
    // https://stackoverflow.com/questions/13744176/codemirror-autocomplete-after-any-keyup
    editor.on("keyup", function(editor, event) {
        var doc = editor.getDoc();
        var POS = doc.getCursor();
        var mode = CodeMirror.innerMode(editor.getMode(), editor.getTokenAt(POS).state).mode.name;
        console.log(mode);
        // CodeMirror.commands.autocomplete(editor, null, {completeSingle: false});
        /*
        !editor.state.completionActive: Enables keyboard navigation in autocomplete list
        key_code != 13: Enter - do not open autocomplete list just after item has been selected in it
        */
        var key_map = [
            8, // Backspace
            9, // Tab
            13, // Enter
            16, //  Shift
            17, // Ctrl
            27, // Esc
            33, // Page Up
            34, // Page Down
            35, // End
            36, // Home
            37, // Left
            38, // Up
            39, // Right
            40, // Down
            46, // Delete
            48, // )
            56, // *
            57, // (
            122, // F11
            186 // ;
        ];
        var key_code = event.keyCode || event.which; 
        if (!editor.state.completionActive && $.inArray(key_code, key_map) == -1) {         
            CodeMirror.commands.autocomplete(editor, null, {completeSingle: false});
            console.log(key_code);
            console.log({
                'ctrl': event.ctrlKey,
                'alt': event.altKey,
                'shift': event.shiftKey,
                'meta': event.metaKey
            });
        }
        /*
        editor.blockComment(
            editor.getCursor("start"),
            editor.getCursor("end"),
            {
                blockCommentStart: "/ *",
                blockCommentEnd: "* /"
            }
        );
        editor.uncomment(
            editor.getCursor("start"),
            editor.getCursor("end"),
            {
                blockCommentStart: "/ *",
                blockCommentEnd: "* /"
            }
        );
        */
    });
    $editor_elem.data('data-editor', editor);


    $('.btn-execute').on('click', function(e) {
        $.ajax({
            url: '/sql-execute',
            method: 'POST',
            data: {
                'value': editor.getValue()
            },
            dataType: 'json',
            success: function(data) {
                console.log(data);
            },
            error: function(xhr) {
                console.log(xhr);
            },
            statusCode: {
                500: function(info) {
                    console.log(info);
                }
            }
        });
    });
});